<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="80%">
    <el-form ref="formRef" v-loading="formLoading" :model="formData" :rules="rules" label-width="130"
      class="max-h-550px overflow-y-auto">
      <ContentItemWrap>
        <template v-slot:title> 基本信息 </template>
        <template v-slot:content>
          <el-container class="flex-wrap">
            <el-form-item label="货源名称" prop="goodsSourceName" class="w-1/2">
              <el-input v-model="formData.goodsSourceName" :maxlength="50" show-word-limit placeholder="如：XX煤矿-XX站台"
                class="!w-full" />
            </el-form-item>
            <el-form-item label="生效时间" prop="startTime" class="w-1/2">
              <el-date-picker v-model="formData.startTime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择生效时间"
                type="datetime" class="!w-full" />
            </el-form-item>
            <el-form-item label="失效时间" prop="endTime" class="w-1/2">
              <el-date-picker v-model="formData.endTime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择失效时间"
                type="datetime" class="!w-full" />
            </el-form-item>
            <el-form-item label="货物名称" prop="productName" class="w-1/2">
              <el-input v-model="formData.productName" :maxlength="20" show-word-limit placeholder="请输入货物名称"
                class="!w-full" />
            </el-form-item>
            <el-form-item label="托运方名称" prop="consignorName" class="w-1/2">
              <el-input v-model="formData.consignorName" :maxlength="50" show-word-limit placeholder="托运企业名称或者联系人称呼"
                class="!w-full" />
            </el-form-item>
            <el-form-item label="托运方电话" prop="consignorPhone" class="w-1/2">
              <el-input v-model="formData.consignorPhone" :maxlength="11" show-word-limit placeholder="请输入托运方电话"
                class="!w-full" />
            </el-form-item>
            <el-container class="!grid grid-cols-[6fr,4fr,1fr] gap-x-20px">
              <el-form-item label="装货地址" prop="loadingPlaceCode">
                <el-cascader ref="loadingCascaderRef" v-model="formData.loadingPlaceCode" :options="addressList"
                  filterable clearable class="!w-full">
                </el-cascader>
              </el-form-item>
              <el-form-item label-width="0">
                <el-input v-model="formData.loadingPlaceName" :maxlength="50" show-word-limit placeholder="请输入详细地址"
                  class="!w-full" />
              </el-form-item>
              <el-form-item label-width="0">
                <el-button type="primary" plain @click="openMapDialog('loading')" class="!w-full">地图选点</el-button>
              </el-form-item>
            </el-container>
            <el-container class="!grid grid-cols-[6fr,4fr,1fr] gap-x-20px">
              <el-form-item label="卸货地址" prop="unloadingPlaceCode">
                <el-cascader ref="unloadingCascaderRef" v-model="formData.unloadingPlaceCode" :options="addressList"
                  filterable clearable class="!w-full">
                </el-cascader>
              </el-form-item>
              <el-form-item label-width="0">
                <el-input v-model="formData.unloadingPlaceName" :maxlength="50" show-word-limit placeholder="请输入详细地址"
                  class="!w-full" />
              </el-form-item>
              <el-form-item label-width="0">
                <el-button type="primary" plain @click="openMapDialog('unloading')" class="!w-full">地图选点</el-button>
              </el-form-item>
            </el-container>
          </el-container>
        </template>
      </ContentItemWrap>
      <ContentItemWrap>
        <template v-slot:title> 运输信息 </template>
        <template v-slot:content>
          <el-container class="flex-wrap">
            <el-form-item label="运价" prop="freight" class="w-1/2">
              <el-input v-model="formData.freight" :maxlength="9" show-word-limit placeholder="请输入运价" class="!w-full">
                <template #append>元/吨</template>
              </el-input>
            </el-form-item>
            <el-form-item label="结算依据" prop="settlementBasis" class="w-1/2">
              <el-select clearable v-model="formData.settlementBasis" placeholder="请选择结算依据" class="!w-full">
                <el-option v-for="dict in getIntDictOptions(DICT_TYPE.SETTLEMENT_BASIS)" :key="dict.value"
                  :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="是否计算路损" prop="isCalculateRoadLoss" class="w-1/2">
              <el-select clearable v-model="formData.isCalculateRoadLoss" placeholder="请选择是否计算路损" class="!w-full">
                <el-option v-for="dict in getIntDictOptions(DICT_TYPE.IS_CALCULATE_ROAD_LOSS)" :key="dict.value"
                  :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item v-if="formData.isCalculateRoadLoss===0" label="合理路损" prop="reasonableRoadLoss" class="w-1/2">
              <el-input v-model="formData.reasonableRoadLoss" :maxlength="9" show-word-limit placeholder="请输入合理路损"
                class="!w-full">
                <template #append>吨</template>
              </el-input>
            </el-form-item>
            <el-form-item v-if="formData.isCalculateRoadLoss===0" label="路损单价" prop="roadLossPrice" class="w-1/2">
              <el-input v-model="formData.roadLossPrice" :maxlength="9" show-word-limit placeholder="请输入路损单价"
                class="!w-full">
                <template #append>元/吨</template>
              </el-input>
            </el-form-item>
            <el-form-item v-if="formData.isCalculateRoadLoss===0" label="路损计算规则" class="w-1/2">
              <el-select clearable v-model="formData.roadLossCalculateRule" placeholder="请选择路损计算规则" class="!w-full">
                <el-option v-for="dict in getIntDictOptions(DICT_TYPE.ROAD_LOSS_CALCULATE_RULE)" :key="dict.value"
                  :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="抹零规则" prop="erasureRule" class="w-1/2">
              <el-select clearable v-model="formData.erasureRule" placeholder="请选择抹零规则" class="!w-full">
                <el-option v-for="dict in getIntDictOptions(DICT_TYPE.ERASURE_RULE)" :key="dict.value"
                  :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="备注" prop="remark" class="!w-full">
              <el-input type="textarea" v-model="formData.remark" :maxlength="100" show-word-limit placeholder="备注"
                class="!w-full" />
            </el-form-item>
          </el-container>
        </template>
      </ContentItemWrap>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
    </template>
    <MapPoints ref="mapPointsRef" :longitudelatitude="longitudelatitude" @success="success"></MapPoints>
  </Dialog>
</template>
<script lang="ts" setup>
  import { cloneDeep } from 'lodash'
  import MapPoints from './mapPoints.vue'
  import * as AreaApi from '@/api/system/area'
  import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
  import * as goodsSourceApi from '@/api/transportation/goodsSource'
  const emit = defineEmits(['success'])
  const mapPointsRef = ref()
  const loadingCascaderRef = ref()
  const unloadingCascaderRef = ref()
  const formRef = ref()
  const dialogTitle = ref('')
  const message = useMessage()
  const dialogVisible = ref(false)
  const formLoading = ref(false)
  const addressList = ref([])
  const mapType = ref()
  const formData = ref({
    id: undefined,
    goodsSourceName: undefined,
    startTime: undefined,
    endTime: undefined,
    productName: undefined,
    consignorName: undefined,
    consignorPhone: undefined,
    loadingPlaceCode: [],
    loadingPlaceName: undefined,
    loadingPlaceCoordinates: [],
    unloadingPlaceName: undefined,
    unloadingPlaceCode: [],
    unloadingPlaceCoordinates: [],
    freight: undefined,
    settlementBasis: undefined,
    isCalculateRoadLoss: undefined,
    reasonableRoadLoss: undefined,
    roadLossPrice: undefined,
    roadLossCalculateRule: undefined,
    erasureRule: undefined,
    remark: undefined,
  })

  const validateStartTime = (rule, date, callback) => {
    if (!date) {
      callback(new Error('请选择生效时间'))
      return
    }
    const start = new Date(date).getTime()
    const end = new Date(formData.value.endTime).getTime()
    if (start >= end) {
      callback(new Error('生效时间不能晚于失效时间'))
      return
    }
    callback()
  }

  const validateEndTime = (rule, date, callback) => {
    if (!date) {
      callback(new Error('请选择失效时间'))
      return
    }
    const start = new Date(formData.value.startTime).getTime()
    const end = new Date(date).getTime()
    if (start >= end) {
      callback(new Error('失效时间不能早于生效时间'))
      return
    }
    callback()
  }

  const validatePhone = (rule, value, callback) => {
    if (!/^\d{8,11}$/.test(value)) {
      callback(new Error('请输入8-11位的电话号码'))
      return
    }
    callback()
  }

  const validateTransAmount = (rule, value, callback) => {
    if (!/^\d+(\.\d{1,2})?$/.test(value)) {
      callback(new Error('请输入0.00-999999.99范围内的合理数值'))
      return
    }
    if (value >= 1000000) {
      callback(new Error('请输入0.00-999999.99范围内的合理数值'))
      return
    }
    if (value < 0) {
      callback(new Error('请输入0.00-999999.99范围内的合理数值'))
      return
    }
    callback()
  }

  const rules = reactive({
    goodsSourceName: [{ required: true, message: '请输入货源名称', trigger: 'blur' }],
    startTime: [{ required: true, message: '请选择生效时间', trigger: 'change' },
    { validator: validateStartTime, trigger: 'change' }],
    endTime: [{ required: true, message: '请选择失效时间', trigger: 'change' },
    { validator: validateEndTime, trigger: 'change' }
    ],
    productName: [{ required: true, message: '请输入货物名称', trigger: 'blur' }],
    consignorName: [{ required: true, message: '请输入托运方名称', trigger: 'blur' }],
    consignorPhone: [{ required: true, message: '请输入8-11位的电话号码', trigger: 'blur' },
    { validator: validatePhone, trigger: 'blur' }],
    loadingPlaceCode: [{ required: true, message: '请选择装货地址', trigger: 'change' }],
    unloadingPlaceCode: [{ required: true, message: '请选择卸货地址', trigger: 'change' }],
    freight: [{ required: true, message: '请输入0.00-999999.99范围内的合理数值', trigger: 'blur' },
    { validator: validateTransAmount, trigger: 'blur' }],
    settlementBasis: [{ required: true, message: '请选择结算依据', trigger: 'change' }],
    isCalculateRoadLoss: [{ required: true, message: '请选择是否计算路损', trigger: 'change' }],
    reasonableRoadLoss: [{ required: true, message: '请输入0.00-999999.99范围内的合理数值', trigger: 'blur' },
    { validator: validateTransAmount, trigger: 'blur' }],
    roadLossPrice: [{ required: true, message: '请输入0.00-999999.99范围内的合理数值', trigger: 'blur' },
    { validator: validateTransAmount, trigger: 'blur' }],
    erasureRule: [{ required: true, message: '请选择路抹零规则', trigger: 'change' }],
  })

  const longitudelatitude = computed(() => {
    if (mapType.value === 'loading') {
      return { lat: formData.value.loadingPlaceCoordinates[0], lng: formData.value.loadingPlaceCoordinates[1] }
    }
    if (mapType.value === 'unloading') {
      return { lat: formData.value.unloadingPlaceCoordinates[0], lng: formData.value.unloadingPlaceCoordinates[1] }
    }
    return { lat: undefined, lng: undefined }
  })

  const open = async (id) => {
    resetFn()
    getAreaTree()
    dialogVisible.value = true
    dialogTitle.value = '编辑货源'
    formData.value.id = id
    getGoodsSource()
  }

  const getAreaTree = async () => {
    const result = await AreaApi.getAreaTree()
    addressList.value = handleResult(result)
  }

  const handleResult = (result) => {
    result.forEach(e => {
      e.value = e.id
      e.label = e.name
      if (e.children?.length) {
        handleResult(e.children)
      }
    })
    return result
  }

  const getGoodsSource = async () => {
    const res = await goodsSourceApi.getGoodsSource({ id: formData.value.id })
    Object.keys(formData.value).forEach((key) => {
      switch (key) {
        case 'loadingPlaceCode':
          formData.value.loadingPlaceCode = [res.loadingPlaceProvinceCode, res.loadingPlaceCityCode, res.loadingPlaceCountyCode, res.loadingPlaceTownCode]
          break;
        case 'loadingPlaceCoordinates':
          formData.value.loadingPlaceCoordinates = res.loadingPlaceCoordinates ? res.loadingPlaceCoordinates.split(',') : []
          break;
        case 'unloadingPlaceCode':
          formData.value.unloadingPlaceCode = [res.unloadingPlaceProvinceCode, res.unloadingPlaceCityCode, res.unloadingPlaceCountyCode, res.unloadingPlaceTownCode]
          break
        case 'unloadingPlaceCoordinates':
          formData.value.unloadingPlaceCoordinates = res.unloadingPlaceCoordinates ? res.unloadingPlaceCoordinates.split(',') : []
          break
        default:
          formData.value[key] = res[key]
          break
      }
    })
  }

  const openMapDialog = (type) => {
    mapType.value = type
    mapPointsRef.value.open()
  }

  const success = (latlng) => {
    if (mapType.value === 'loading') {
      formData.value.loadingPlaceCoordinates = [latlng.lat, latlng.lng]
    }
    if (mapType.value === 'unloading') {
      formData.value.unloadingPlaceCoordinates = [latlng.lat, latlng.lng]
    }
  }

  const getBody = () => {
    const data = cloneDeep(formData.value)
    const loadingPlaceLabel = loadingCascaderRef.value.getCheckedNodes()?.[0]?.pathLabels || []
    const unloadingPlaceLabel = unloadingCascaderRef.value.getCheckedNodes()?.[0]?.pathLabels || []
    data['loadingPlaceProvinceCode'] = data.loadingPlaceCode[0]
    data['loadingPlaceCityCode'] = data.loadingPlaceCode[1]
    data['loadingPlaceCountyCode'] = data.loadingPlaceCode[2]
    data['loadingPlaceTownCode'] = data.loadingPlaceCode[3]
    data['loadingPlaceProvinceName'] = loadingPlaceLabel[0]
    data['loadingPlaceCityName'] = loadingPlaceLabel[1]
    data['loadingPlaceCountyName'] = loadingPlaceLabel[2]
    data['loadingPlaceTownName'] = loadingPlaceLabel[3]
    data['unloadingPlaceProvinceCode'] = data.unloadingPlaceCode[0]
    data['unloadingPlaceCityCode'] = data.unloadingPlaceCode[1]
    data['unloadingPlaceCountyCode'] = data.unloadingPlaceCode[2]
    data['unloadingPlaceTownCode'] = data.unloadingPlaceCode[3]
    data['unloadingPlaceProvinceName'] = unloadingPlaceLabel[0]
    data['unloadingPlaceCityName'] = unloadingPlaceLabel[1]
    data['unloadingPlaceCountyName'] = unloadingPlaceLabel[2]
    data['unloadingPlaceTownName'] = unloadingPlaceLabel[3]
    data.loadingPlaceCoordinates = data.loadingPlaceCoordinates.join(',')
    data.unloadingPlaceCoordinates = data.unloadingPlaceCoordinates.join(',')
    delete data.loadingPlaceCode
    delete data.unloadingPlaceCode
    return data
  }

  const submitForm = async () => {
    if (!formRef) return
    const valid = await formRef.value.validate()
    if (!valid) return
    try {
      formLoading.value = true
      await goodsSourceApi.updateGoodsSource(getBody())
      message.success('操作成功')
      dialogVisible.value = false
      emit('success')
    } finally {
      formLoading.value = false
    }
  }

  const resetFn = () => {
    Object.keys(formData.value).forEach(key => {
      if (['loadingPlaceCode', 'loadingPlaceCoordinates', 'unloadingPlaceCode', 'unloadingPlaceCoordinates'].includes(key)) {
        formData.value[key] = []
      } else {
        formData.value[key] = undefined
      }
    })
    formRef.value?.resetFields()
  }

  defineExpose({ open })
</script>
<style lang="scss" scoped>
  :deep(.el-input__wrapper) {
    width: 100%;
  }

  :deep(.el-button--primary.is-plain) {
    background-color: #ffffff !important;
  }

  :deep(.el-button:focus),
  :deep(.el-button:hover) {
    color: var(--el-color-primary) !important;
  }
</style>